MODULE md1_global_types

   IMPLICIT NONE
   PUBLIC   

!------------------------------------------------------------------------------

   ! We select here the REAL and INTEGER precisions
   !   INTEGER, PARAMETER :: md1_INTK  = SELECTED_INT_KIND(9),           &
   !                         md1_REALK = SELECTED_REAL_KIND(XXX) 
   ! Use standard integers and REAL*8 double precision floats
   INTEGER, PARAMETER :: md1_INTK  = KIND(1),                         &
                         md1_REALK = KIND(1D0) 

!===============================================================================

   TYPE md1_real_hilo
      REAL(md1_REALK) :: hi, lo
   END TYPE md1_real_hilo

!------------------------------------------------------------------------------

   TYPE md1_int_hilo
      INTEGER(md1_INTK) :: hi, lo
   END TYPE md1_int_hilo

!------------------------------------------------------------------------------

   ! O(N) array of non-vanishing shell paris
   TYPE md1_sh_pairs
      ! Index of first and last Cartesian AO in this shell
      TYPE(md1_int_hilo) :: P, Q
!      ! Spatial range
!      TYPE(md1_real_hilo) :: extent
      ! Centres of two shells making up pair
      REAL(md1_REALK) :: A(3), B(3)
      ! Centre (definition can vary)
      REAL(md1_REALK) :: xyz(3)
      ! Shell indices
      INTEGER(md1_INTK) :: I, J
      ! Angular momentum
      INTEGER(md1_INTK) :: Iang, Jang
   END TYPE md1_sh_pairs

!------------------------------------------------------------------------------

   ! Batch of primitive pairs for one shell-pair
   TYPE md1_prim_batch
      REAL(md1_REALK)   :: P(3), PA(3), PB(3)
      REAL(md1_REALK)   :: exp
      REAL(md1_REALK)   :: KAB
      REAL(md1_REALK)   :: CAB
      REAL(md1_REALK)   :: fmm_extent
   END TYPE md1_prim_batch

!------------------------------------------------------------------------------

   ! Gaussian AO basis set information
   TYPE md1_basis

      ! Total number of atoms
      INTEGER(md1_INTK) :: natom
      ! Total number of Cartesian basis functions
      INTEGER(md1_INTK) :: nbas
      ! Total number of shells
      INTEGER(md1_INTK) :: nshell
      ! Maximum angular momentum in basis set
      INTEGER(md1_INTK) :: Lmax
      ! Largest primitive batch for any shell-pair (square of max contraction)
      INTEGER(md1_INTK) :: Cmax2

      ! Co-ordinates of atomic centres
      REAL(md1_REALK), POINTER :: xyz(:,:)
      ! Array of AO primitive exponents
      REAL(md1_REALK), POINTER :: exp(:)
      ! Array of AO contraction coefficients
      REAL(md1_REALK), POINTER :: C(:)

      ! Map from shell index to atom index
      INTEGER(md1_INTK), POINTER :: atom(:)
      ! Angular momentum of this shell
      INTEGER(md1_INTK), POINTER :: L(:)

      ! Map from shell index to 1st primitive exponent in this shell
      INTEGER(md1_INTK), POINTER :: exp_id(:)
      ! Number of contracted primitive exponents in this shell
      INTEGER(md1_INTK), POINTER :: nprim(:)

      ! Index of first Cartesian AO component from this shell
      INTEGER(md1_INTK), POINTER :: car_AO(:)
      ! Index of first Spherical AO component from this shell
      INTEGER(md1_INTK), POINTER :: sph_AO(:)

      ! Spherical and cartesian component information
      TYPE(md1_basis_LM), POINTER :: LM(:)

   END TYPE md1_basis

!------------------------------------------------------------------------------

   TYPE md1_basis_LM

      ! Number of Cartesian components for this L-value (e.g. d-shell = 6)
      INTEGER(md1_INTK) :: car_nlm
      ! Number of Spherical components for this L-value (e.g. d-shell = 5)
      INTEGER(md1_INTK) :: sph_nlm
      ! xyz-powers for each Cartesian component (see int_basis_set.f90)
      INTEGER(md1_INTK), POINTER :: tuv(:,:)

   END TYPE md1_basis_LM

!------------------------------------------------------------------------------

   TYPE md1_FE_grid
      ! Order of the shape functions (using Lagrange IP currently)
      INTEGER(md1_INTK) :: order
      ! Total grid size in x,y,z
      INTEGER(md1_INTK) :: n(3)
      ! Length of each finite element
      REAL(md1_REALK) :: L(3)
      ! Spacing between "grid" points in each finite element
      REAL(md1_REALK) :: h(3)
      ! Extremum co-ordinates of whole grid
      REAL(md1_REALK) :: lo(3), hi(3)
      ! Grid point values
      REAL(md1_REALK), POINTER :: f(:,:,:)
   END TYPE md1_FE_grid

!------------------------------------------------------------------------------

   TYPE md1_5d_array
      INTEGER(md1_INTK) :: n
      REAL(md1_REALK), POINTER :: a(:,:,:,:,:)
   END TYPE md1_5d_array

!------------------------------------------------------------------------------

   TYPE md1_charge
      INTEGER(md1_INTK) :: q
      REAL(md1_REALK)   :: xyz(3)
   END TYPE md1_charge

!------------------------------------------------------------------------------

END MODULE md1_global_types

